#region license
/*
 * Copyright (C) 2007 CchenSoft.com
 * 
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License 2.1 or later, as
 * published by the Free Software Foundation. See the included License.txt
 * or http://www.gnu.org/copyleft/lesser.html for details.
 * 
 * Author: Billy Zhang
 */
#endregion

using System.Collections;
using System.Xml;
using System.Collections.Generic;

namespace CchenSoft.Workflow.Loader
{
    public class ConditionsDescriptor : BaseConditionDescriptor
    {
        //~ Instance fields ////////////////////////////////////////////////////////

        private IList<BaseConditionDescriptor> conditions = new List<BaseConditionDescriptor>();

        //~ Constructors ///////////////////////////////////////////////////////////

        /**
         * @deprecated use {@link DescriptorFactory} instead
         */
        public ConditionsDescriptor()
        {
        }

        /**
         * @deprecated use {@link DescriptorFactory} instead
         */
        public ConditionsDescriptor(XmlElement element) : base(element)
        {
            XmlNodeList children = element.ChildNodes;

            for (int i = 0; i < children.Count; i++)
            {
                XmlNode child = children[i];

                if (child.NodeType == XmlNodeType.Element)
                {
                    if ("condition".Equals(child.Name))
                    {
                        ConditionDescriptor condition = DescriptorFactory.GetFactory().CreateConditionDescriptor((XmlElement)child);
                        conditions.Add(condition);
                    }
                    else if ("conditions".Equals(child.Name))
                    {
                        ConditionsDescriptor condition = DescriptorFactory.GetFactory().CreateConditionsDescriptor((XmlElement)child);
                        conditions.Add(condition);
                    }
                }
            }
        }

        //~ Methods ////////////////////////////////////////////////////////////////

        public IList<BaseConditionDescriptor> Conditions
        {
            set { conditions = value; }
            get { return conditions; }
        }

        public override void Validate()
        {
            ValidationHelper.Validate((ICollection<IValidatable>)conditions);

            if (conditions.Count == 0)
            {
                AbstractDescriptor desc = Parent;

                if ((desc != null) && (desc is ConditionalResultDescriptor))
                {
                    throw new InvalidWorkflowDescriptorException("Conditional result from " + ((ActionDescriptor)desc.Parent).Name + " to " + ((ConditionalResultDescriptor)desc).GetDestination() + " must have at least one condition");
                }
            }

            if ((conditions.Count > 1) && (type == null))
            {
                throw new InvalidWorkflowDescriptorException("Conditions must have AND or OR type specified");
            }
        }

        public override void WriteXML(XmlTextWriter writer, int indent)
        {
            if (conditions.Count > 0)
            {
                XMLUtil.printIndent(writer, indent++);

                writer.WriteStartElement("conditions");

                if (conditions.Count > 1)
                {
                    writer.WriteAttributeString("type", type);
                }

                for (int i = 0; i < conditions.Count; i++)
                {
                    IXMLizable condition = (IXMLizable)conditions[i];
                    condition.WriteXML(writer, indent);
                }

                XMLUtil.printIndent(writer, --indent);
                writer.WriteEndElement(); //("</conditions>");
            }
        }
    }
}
